////////////////////////////////////////////////////////////////////////////////
//
//  FLEX USER GROUP HOKURIKU
//  Copyright 2009 Flex User Group Hokuriku
//  All Rights Reserved.
// 
//  NOTICE: Flex User Group Hokuriku permits you to use, 
//  modify, and distribute this file 
//  in accordance with the terms of the license agreement accompanying it.
//
////////////////////////////////////////////////////////////////////////////////
package net.fxug.hokuriku.chocolat.helper
{
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.utils.Dictionary;

    import mx.core.IMXMLObject;
    import mx.events.FlexEvent;
    import mx.logging.ILogger;

    import net.fxug.hokuriku.chocolat.events.SessionTimerEvent;
    import net.fxug.hokuriku.chocolat.events.VoteEvent;
    import net.fxug.hokuriku.chocolat.events.VoteStatusEvent;
    import net.fxug.hokuriku.chocolat.model.ApplicationDataModel;
    import net.fxug.hokuriku.chocolat.model.SessionTimer;
    import net.fxug.hokuriku.chocolat.model.VoteData;
    import net.fxug.hokuriku.chocolat.model.VoteInfo;
    import net.fxug.hokuriku.chocolat.service.VoteManager;
    import net.fxug.hokuriku.chocolat.utils.EventUtil;
    import net.fxug.hokuriku.chocolat.utils.LoggingUtil;
    import net.fxug.hokuriku.chocolat.view.DigitalTimerControl;
    import net.fxug.hokuriku.chocolat.view.NotificationManager;
    import net.fxug.hokuriku.chocolat.view.TimelineTimer;

    /**
     * タイマーコントロール(View)のヘルパークラス
     *
     * @author shoito
     */
    public class DigitalTimerControlHelper implements IMXMLObject
    {
        /** ロガー */
        private static var logger:ILogger = LoggingUtil.getLogger(DigitalTimerControlHelper);

        private var view:DigitalTimerControl

        private var sessionTimer:SessionTimer;

        private var timelineTimer:TimelineTimer;

        private var timeFormatter:TimeFormatter;

        /** 通知上限に達したユーザ情報のMap */
        private var limitUserMap:Dictionary = new Dictionary();

        private var voteManager:VoteManager;

        public function initialized(document:Object, id:String):void
        {
            this.view = document as DigitalTimerControl;
            this.view.addEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler);

            this.timeFormatter = new TimeFormatter();
            this.voteManager = VoteManager.getInstance();
        }

        private function creationCompleteHandler(event:FlexEvent):void
        {
            this.sessionTimer = SessionTimer.getInstance();
            this.sessionTimer.addEventListener(Event.CHANGE, sessionTimer_changeHandler);
            this.view.addEventListener(MouseEvent.DOUBLE_CLICK, doubleClickHandler);
            this.view.time.addEventListener(MouseEvent.DOUBLE_CLICK, doubleClickHandler);

            // タイムライン描画が完了した時点で、Popup通知領域のイベントを設定する。
            this.voteManager.addEventListener(VoteEvent.GOOD_EVENT, voteManager_voteEventHandler);
            this.voteManager.addEventListener(VoteEvent.BAD_EVENT, voteManager_voteEventHandler);
            this.voteManager.addEventListener(VoteStatusEvent.MAX_VOTE_EVENT, maxVoteEventHandler);

            timelineTimer = new TimelineTimer();
            timelineTimer.addEventListener(Event.CLOSE, timelineTimer_closeHandler);
            timelineTimer.visible = true;

            sessionTimer_changeHandler();
        }

        private function sessionTimer_changeHandler(event:Event = null):void
        {
            this.view.time.text = timeFormatter.format(sessionTimer.remainingTime);
        }

        private function voteManager_voteEventHandler(voteEvent:VoteEvent):void
        {
            if (voteEvent.tweetArray == null || voteEvent.tweetArray.length == 0)
            {
                return;
            }
            var index:int = voteEvent.tweetArray.length;
            for (var i:int = 0; i < index; i++)
            {
                var voteData:VoteData = voteEvent.tweetArray[i];
                NotificationManager.getInstance().notify(EventUtil.fromVoteEventToNotifyManagerType(voteEvent), voteData.text, voteData.id, voteData.link);

                // カウントアップ
                // FIXME #3の暫定対応
                ApplicationDataModel.getInstance().addVote(voteEvent.type);

                // つぶやき自体が無効の場合はタイムラインへの反映を行わない
                if (!voteData.voteEnabled)
                {
                    logger.info("This tweet[{0}:{1}:{2}] already limit. so not apperd", voteData.id, voteData.text, voteData.route);
                    continue;
                }
                logger.debug("Vote apperd[{0}] timeline", voteData);
                var gravity:int = (voteEvent.type == VoteEvent.GOOD_EVENT) ? 5 * 1000 : -3 * 1000;
                sessionTimer.adjustBonus(gravity);
            }
        }

        private function maxVoteEventHandler(voteStatuEvent:VoteStatusEvent):void
        {
            var voteInfo:VoteInfo = voteStatuEvent.value as VoteInfo;
            this.limitUserMap[voteInfo.userId] = voteInfo;
        }

        private function doubleClickHandler(event:MouseEvent):void
        {
            // TODO 確認
            timeUp();
        }

        private function sessionTimer_timeUpHandler(event:Event):void
        {
            timeUp();
        }

        private function timelineTimer_closeHandler(event:Event):void
        {
            timeUp();
        }

        private function timeUp():void
        {
            this.voteManager.removeEventListener(VoteEvent.GOOD_EVENT, voteManager_voteEventHandler);
            this.voteManager.removeEventListener(VoteEvent.BAD_EVENT, voteManager_voteEventHandler);
            this.voteManager.removeEventListener(VoteStatusEvent.MAX_VOTE_EVENT, maxVoteEventHandler);
            this.voteManager.close();

            this.view.dispatchEvent(new SessionTimerEvent(SessionTimerEvent.TIME_UP));
        }
    }
}